{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from __future__ import absolute_import\n",
    "from __future__ import division\n",
    "from __future__ import print_function\n",
    "import argparse\n",
    "import sys\n",
    "import tensorflow as tf\n",
    "from tensorflow.examples.tutorials.mnist import input_data\n",
    "from keras.models import Sequential\n",
    "from keras.layers import Dense, Dropout, Flatten\n",
    "from keras.layers.convolutional import Conv2D\n",
    "from keras.layers.pooling import MaxPooling2D\n",
    "from keras import backend as K\n",
    "from tinyenv.flags import flags\n",
    "FLAGS = None\n",
    "\n",
    "#载入数据\n",
    "data_dir = '/data/weixin-40183383/mnist/MNIST_data'\n",
    "mnist = input_data.read_data_sets(data_dir, one_hot=True) \n",
    "\n",
    "#把图片reshape为4维张量\n",
    "X_train, Y_train = mnist.train.images,mnist.train.labels  \n",
    "X_test, Y_test = mnist.test.images, mnist.test.labels \n",
    "X_train = X_train.reshape(-1, 28, 28,1).astype('float32')  \n",
    "X_test = X_test.reshape(-1,28, 28,1).astype('float32')\n",
    "#X_train /= 255\n",
    "#X_test /= 255  \n",
    "\n",
    "#CNN框架，借鉴VGG网络的前几层结构，激活函数使用relu\n",
    "model = Sequential()\n",
    "#两个卷积层feature map 扩展为32，一个下采样层把图片只存变为14*14\n",
    "model.add(Conv2D(32,(3,3),strides=(1,1),input_shape=(28,28,1),padding='same',activation='relu'))  \n",
    "model.add(Conv2D(32,(3,3),strides=(1,1),padding='same',activation='relu'))  \n",
    "model.add(MaxPooling2D(pool_size=(2,2)))  \n",
    "\n",
    "#两个卷积层feature map 扩展为64，一个下采样层把图片只存变为7*7\n",
    "model.add(Conv2D(64,(3,2),strides=(1,1),padding='same',activation='relu'))  \n",
    "model.add(Conv2D(64,(3,3),strides=(1,1),padding='same',activation='relu'))  \n",
    "model.add(MaxPooling2D(pool_size=(2,2)))  \n",
    "\n",
    "#两个卷积层feature map 扩展为128，一个下采样层把图片只存变为3*3\n",
    "model.add(Conv2D(128,(3,3),strides=(1,1),padding='same',activation='relu'))  \n",
    "model.add(Conv2D(128,(3,3),strides=(1,1),padding='same',activation='relu'))  \n",
    "model.add(MaxPooling2D(pool_size=(2,2)))   \n",
    "\n",
    "#全连接层\n",
    "model.add(Flatten())  \n",
    "model.add(Dense(256,activation='relu'))  \n",
    "model.add(Dropout(0.5))  \n",
    "model.add(Dense(256,activation='relu'))  \n",
    "model.add(Dropout(0.5))  \n",
    "\n",
    "#全连接为10维向量，再利用softmax函数进行分类\n",
    "model.add(Dense(10,activation='softmax'))  \n",
    "model.summary()\n",
    "\n",
    "#损失函数选择交叉熵损失，优化器使用‘ADAM',默认学习率为0.001\n",
    "model.compile(loss='categorical_crossentropy',\n",
    "              optimizer='adam',\n",
    "              metrics=['accuracy'])\n",
    "\n",
    "#训练模型，batch_size设为200，循环20个epoch\n",
    "model.fit(X_train, Y_train, batch_size = 200,epochs = 20,verbose = 1,validation_data = (X_test, Y_test))\n",
    "score = model.evaluate(X_test, Y_test, verbose=0)\n",
    "print('Test score:', score[0])\n",
    "print('Test accuracy:', score[1])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 下面是在tinymind上的运行结果，最后在测试集上的准确率达到99.36% "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Using TensorFlow backend.\n",
    "Successfully downloaded train-images-idx3-ubyte.gz 9912422 bytes.\n",
    "Extracting /data/weixin-40183383/mnist/MNIST_data/train-images-idx3-ubyte.gz\n",
    "Successfully downloaded train-labels-idx1-ubyte.gz 28881 bytes.\n",
    "Extracting /data/weixin-40183383/mnist/MNIST_data/train-labels-idx1-ubyte.gz\n",
    "Successfully downloaded t10k-images-idx3-ubyte.gz 1648877 bytes.\n",
    "Extracting /data/weixin-40183383/mnist/MNIST_data/t10k-images-idx3-ubyte.gz\n",
    "Successfully downloaded t10k-labels-idx1-ubyte.gz 4542 bytes.\n",
    "Extracting /data/weixin-40183383/mnist/MNIST_data/t10k-labels-idx1-ubyte.gz\n",
    "_________________________________________________________________\n",
    "Layer (type)                 Output Shape              Param #   \n",
    "=================================================================\n",
    "conv2d_1 (Conv2D)            (None, 28, 28, 32)        320       \n",
    "_________________________________________________________________\n",
    "conv2d_2 (Conv2D)            (None, 28, 28, 32)        9248      \n",
    "_________________________________________________________________\n",
    "max_pooling2d_1 (MaxPooling2 (None, 14, 14, 32)        0         \n",
    "_________________________________________________________________\n",
    "conv2d_3 (Conv2D)            (None, 14, 14, 64)        12352     \n",
    "_________________________________________________________________\n",
    "conv2d_4 (Conv2D)            (None, 14, 14, 64)        36928     \n",
    "_________________________________________________________________\n",
    "max_pooling2d_2 (MaxPooling2 (None, 7, 7, 64)          0         \n",
    "_________________________________________________________________\n",
    "conv2d_5 (Conv2D)            (None, 7, 7, 128)         73856     \n",
    "_________________________________________________________________\n",
    "conv2d_6 (Conv2D)            (None, 7, 7, 128)         147584    \n",
    "_________________________________________________________________\n",
    "max_pooling2d_3 (MaxPooling2 (None, 3, 3, 128)         0         \n",
    "_________________________________________________________________\n",
    "flatten_1 (Flatten)          (None, 1152)              0         \n",
    "_________________________________________________________________\n",
    "dense_1 (Dense)              (None, 256)               295168    \n",
    "_________________________________________________________________\n",
    "dropout_1 (Dropout)          (None, 256)               0         \n",
    "_________________________________________________________________\n",
    "dense_2 (Dense)              (None, 256)               65792     \n",
    "_________________________________________________________________\n",
    "dropout_2 (Dropout)          (None, 256)               0         \n",
    "_________________________________________________________________\n",
    "dense_3 (Dense)              (None, 10)                2570      \n",
    "=================================================================\n",
    "Total params: 643,818\n",
    "Trainable params: 643,818\n",
    "Non-trainable params: 0\n",
    "_________________________________________________________________\n",
    "Train on 55000 samples, validate on 10000 samples\n",
    "Epoch 1/20\n",
    "2018-07-04 11:00:48.205944: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:893] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n",
    "2018-07-04 11:00:48.206371: I tensorflow/core/common_runtime/gpu/gpu_device.cc:940] Found device 0 with properties: \n",
    "name: Tesla K80\n",
    "major: 3 minor: 7 memoryClockRate (GHz) 0.8235\n",
    "pciBusID 0000:00:04.0\n",
    "Total memory: 11.17GiB\n",
    "Free memory: 11.09GiB\n",
    "2018-07-04 11:00:48.206417: I tensorflow/core/common_runtime/gpu/gpu_device.cc:961] DMA: 0 \n",
    "2018-07-04 11:00:48.206439: I tensorflow/core/common_runtime/gpu/gpu_device.cc:971] 0:   Y \n",
    "2018-07-04 11:00:48.243432: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1030] Creating TensorFlow device (/gpu:0) -> (device: 0, name: Tesla K80, pci bus id: 0000:00:04.0)\n",
    "  355000/55000 [==============================] - 27s - loss: 0.3668 - acc: 0.8815 - val_loss: 0.0574 - val_acc: 0.9820\n",
    "Epoch 2/20\n",
    "155000/55000 [==============================] - 13s - loss: 0.0795 - acc: 0.9789 - val_loss: 0.0373 - val_acc: 0.9893\n",
    "Epoch 3/20\n",
    "155000/55000 [==============================] - 14s - loss: 0.0516 - acc: 0.9861 - val_loss: 0.0386 - val_acc: 0.9885\n",
    "Epoch 4/20\n",
    "155000/55000 [==============================] - 14s - loss: 0.0404 - acc: 0.9889 - val_loss: 0.0353 - val_acc: 0.9907\n",
    "Epoch 5/20\n",
    "155000/55000 [==============================] - 14s - loss: 0.0353 - acc: 0.9901 - val_loss: 0.0228 - val_acc: 0.9933\n",
    "Epoch 6/20\n",
    "155000/55000 [==============================] - 14s - loss: 0.0278 - acc: 0.9920 - val_loss: 0.0294 - val_acc: 0.9912\n",
    "Epoch 7/20\n",
    "155000/55000 [==============================] - 14s - loss: 0.0233 - acc: 0.9936 - val_loss: 0.0283 - val_acc: 0.9929\n",
    "Epoch 8/20\n",
    "155000/55000 [==============================] - 14s - loss: 0.0229 - acc: 0.9934 - val_loss: 0.0245 - val_acc: 0.9932\n",
    "Epoch 9/20\n",
    "155000/55000 [==============================] - 13s - loss: 0.0182 - acc: 0.9948 - val_loss: 0.0239 - val_acc: 0.9943\n",
    "Epoch 10/20\n",
    "155000/55000 [==============================] - 13s - loss: 0.0191 - acc: 0.9946 - val_loss: 0.0228 - val_acc: 0.9943\n",
    "Epoch 11/20\n",
    "155000/55000 [==============================] - 13s - loss: 0.0150 - acc: 0.9954 - val_loss: 0.0295 - val_acc: 0.9931\n",
    "Epoch 12/20\n",
    "155000/55000 [==============================] - 13s - loss: 0.0142 - acc: 0.9958 - val_loss: 0.0267 - val_acc: 0.9939\n",
    "Epoch 13/20\n",
    "155000/55000 [==============================] - 13s - loss: 0.0121 - acc: 0.9965 - val_loss: 0.0344 - val_acc: 0.9938\n",
    "Epoch 14/20\n",
    "  60155000/55000 [==============================] - 13s - loss: 0.0151 - acc: 0.9962 - val_loss: 0.0316 - val_acc: 0.9936\n",
    "Epoch 15/20\n",
    "  60155000/55000 [==============================] - 13s - loss: 0.0114 - acc: 0.9969 - val_loss: 0.0314 - val_acc: 0.9924\n",
    "Epoch 16/20\n",
    "155000/55000 [==============================] - 13s - loss: 0.0118 - acc: 0.9968 - val_loss: 0.0261 - val_acc: 0.9941\n",
    "Epoch 17/20\n",
    "155000/55000 [==============================] - 13s - loss: 0.0113 - acc: 0.9967 - val_loss: 0.0305 - val_acc: 0.9938\n",
    "Epoch 18/20\n",
    "  60155000/55000 [==============================] - 13s - loss: 0.0097 - acc: 0.9973 - val_loss: 0.0319 - val_acc: 0.9944\n",
    "Epoch 19/20\n",
    "  80155000/55000 [==============================] - 13s - loss: 0.0111 - acc: 0.9972 - val_loss: 0.0261 - val_acc: 0.9943\n",
    "Epoch 20/20\n",
    "155000/55000 [==============================] - 13s - loss: 0.0081 - acc: 0.9977 - val_loss: 0.0335 - val_acc: 0.9936\n",
    "Test score: 0.0334913185838\n",
    "Test accuracy: 0.9936"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
